﻿using System;
using System.Collections.Generic;
using System.Linq;
using Nxg.Blog.Core.Documents;

namespace Nxg.Blog.Core.ViewProjections.Home
{
    public class BlogPostDetailsBindingModel
    {
        public string Permalink { get; set; }
    }

    public class BlogPostDetailsViewModel
    {
        public int Id { get; set; }

        public string Title { get; set; }

        public string TitleSlug { get; set; }

        public int ViewCount { get; set; }

        public string MarkDown { get; set; }

        public string Content { get; set; }

        public PublishStatus Status { get; set; }

        public DateTime PubDate { get; set; }

        public DateTime DateUTC { get; set; }

        public string[] Tags { get; set; }

        public string AuthorDisplayName { get; set; }

        public string AuthorEmail { get; set; }

        public Category Category { get; set; }

        public string Link { get; set; }

        public List<BlogComment> Comments { get; set; }

        public (string, string) Next { get; set; }

        public (string, string) Pre { get; set; }
    }

    public class BlogPostDetailsViewProjection : IViewProjection<BlogPostDetailsBindingModel, BlogPostDetailsViewModel>
    {
        private readonly DataContext _context;

        public BlogPostDetailsViewProjection(DataContext context)
        {
            _context = context;
        }

        public BlogPostDetailsViewModel Project(BlogPostDetailsBindingModel input)
        {
            var post = _context.Post.FirstOrDefault(x => x.TitleSlug == input.Permalink);
            if (post == null)
                return null;
            post.ViewCount++;
            _context.SaveChanges();

            var pre = _context.Post.Where(x => x.PubDate <= DateTime.Now && x.Status == PublishStatus.Published && x.PubDate < post.PubDate).OrderByDescending(x => x.PubDate).FirstOrDefault();
            var next = _context.Post.Where(x => x.PubDate <= DateTime.Now && x.Status == PublishStatus.Published && x.PubDate > post.PubDate).OrderBy(x => x.PubDate).FirstOrDefault();

            var comments = _context.Comment.Where(x => x.PostId == post.Id).OrderBy(o => o.CreatedTime).ToList();
            return new BlogPostDetailsViewModel
            {
                Id = post.Id,
                Tags = post.Tags.Split(','),
                AuthorDisplayName = post.AuthorDisplayName,
                AuthorEmail = post.AuthorEmail,
                Content = System.Web.HttpUtility.UrlDecode(post.Content),
                MarkDown = post.MarkDown,
                PubDate = post.PubDate,
                Status = post.Status,
                Title = post.Title,
                TitleSlug = post.TitleSlug,
                ViewCount = post.ViewCount,
                Link = post.GetLink(),
                Category = _context.Category.FirstOrDefault(x => x.Id == post.CategoryId),
                Comments = comments,
                Pre = (pre?.Title, pre?.GetLink()),
                Next = (next?.Title, next?.GetLink())
            };
        }
    }
}